/* uifactory.vala
 *
 * Copyright (C) 2008  Frederik 'playya' Sdun
 *
 * This program is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 2 of the License, or
 * (at your option) any later version.
 *
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with this program.  If not, see <http://www.gnu.org/licenses/>.
 *
 * Author:
 * 	Frederik 'playya' Sdun <Frederik.Sdun@gmail.com>
 */

using GLib;

namespace Rob
{
	namespace UI
	{
		public class RuleFactory: GLib.Object
		{
			string libpath ;
			private delegate Type RegisterPluginFunction ();

			private HashTable< string, GLib.Type > mappings;
			
			construct
			{
				GLib.assert( Module.supported());
				// i know this is evil. will be moved to a configfile soon
				this.libpath = "/usr/lib/rob/rule/";
				this.mappings = new GLib.HashTable<string, GLib.Type>( GLib.str_hash, GLib.str_equal );
				GLib.KeyFile kf = new GLib.KeyFile();
				kf.load_from_file("/etc/rob/rules.conf", GLib.KeyFileFlags.KEEP_COMMENTS | GLib.KeyFileFlags.KEEP_TRANSLATIONS );
				load(kf);	
			}
	
			public Rob.UI.RuleWidget create( KeyFile kf, string name) throws GLib.KeyFileError
			{
				Rob.UI.RuleWidget r;
				string type;
				type  = kf.get_string(name, "type");
		
				GLib.Type objtype = mappings.lookup(type);

				r = (Rob.UI.RuleWidget) @new(objtype);
				
				//r.load( kf, kf.get_string(name, "name" ) );
				return r;
			}
			public void load(KeyFile kf)
			{
				string[] srules = kf.get_groups();
				foreach( string r in srules )
				{
					string path;
					try
					{
						path = kf.get_string(r, "gtkpath");
					}
					catch( GLib.KeyFileError e )
					{
						GLib.critical(_("Can't find gtkpath for %s"), r);
						continue;
					}
					if(!path.has_prefix("/"))
						path = libpath.concat(path);
					GLib.Module module = Module.open (path, GLib.ModuleFlags.BIND_LAZY);
					if( module  != null)
					{
						string func_name;
						try
						{
							func_name = kf.get_string( r, "gtkinit");
						}
						catch ( GLib.KeyFileError e )
						{
							GLib.critical("Can't find gtkinit for %s\n", r);
							continue;
						}	
						void * function;
						module.symbol(func_name, out function);
						RegisterPluginFunction rpf = (RegisterPluginFunction) function;
						GLib.Type type = rpf();
						mappings.insert(r, type);
					}
					else
						GLib.critical("could not load library: %s", path);
				}
			}
		}
		
	
		public class ActionFactory: GLib.Object
		{
			string libpath ;
			private delegate Type RegisterPluginFunction ();
			private GLib.HashTable<string, GLib.Type> mappings;

			construct
			{
				// i know this is evil. will be moved to a configfile soon
				this.libpath = "/usr/lib/rob/action/";
				GLib.assert( Module.supported());
				this.mappings = new GLib.HashTable<string, GLib.Type>( GLib.str_hash, GLib.str_equal );
				GLib.KeyFile kf = new GLib.KeyFile();
				kf.load_from_file("/etc/rob/actions.conf", GLib.KeyFileFlags.KEEP_COMMENTS | GLib.KeyFileFlags.KEEP_TRANSLATIONS );
				load(kf);
			}

			public Rob.UI.ActionWidget create( KeyFile kf, string name) throws GLib.KeyFileError
			{
				Rob.UI.ActionWidget aw;
				string type;


				type  = kf.get_string(name, "type");

				GLib.Type objtype = mappings.lookup(type);

				aw = (Rob.UI.ActionWidget ) @new(objtype);

				return aw;
				
			}
			public void load (KeyFile kf)
			{
			
				string[] sactions = kf.get_groups();
				foreach( string a in sactions )
				{
					string path;
					try
					{
						path = kf.get_string(a, "gtkpath");
					}
					catch( GLib.KeyFileError e)
					{
						GLib.critical("could not load gtkpath for %s", a);
					}
					if(!path.has_prefix("/"))
						path = libpath.concat(path);
					GLib.Module module = Module.open (path, GLib.ModuleFlags.BIND_LAZY);
					if( module != null )
					{
						string func_name;
						try
						{
							func_name = kf.get_string( a, "gtkinit");
						}
						catch ( GLib.KeyFileError e )
						{
							GLib.critical("could not find actioninit for %s\n", a);
							continue;
						}	
						void * function;
						module.symbol(func_name, out function);
						RegisterPluginFunction rpf = (RegisterPluginFunction) function;
						GLib.Type type = rpf();
						mappings.insert(a, type);
					}
					else
						GLib.critical("could not load library: %s", path);
				}
			}

		}

	}
	
}
